<template>
  <div class="spec-preview">
    <img :src="defaultImg" />
    <!--
      event 盒子是用来绑定鼠标事件的,专门写了个盒子来做事件绑定
      这里为什么不拿容器来绑定事件,非要创建一个event盒子专门做这件事?
      给容器或其他元素绑定事件的时候,鼠标事件会有问题
    -->
    <div class="event" ref="eventRef" @mousemove="moveHandler"></div>
    <div class="big">
      <img :src="defaultImg" ref="bigImgRef"/>
    </div>
    <div class="mask" ref="maskRef"></div>
  </div>
</template>

<script>
export default {
  name: "Zoom",
  // 放大镜只展示一张图片,为什么要把所有的图片传入?
  // 因为后续点击的时候,图片还是要切换的
  // 现在把图片列表传入,到时候告诉我是第几张,我们自己在当前组件去取这一张即可
  props: ['skuImageList'],
  data() {
    return {
      index: 0 // 初始值为0,默认展示下标为0的图片
    }
  },
  computed: {
    // 当前展示的这张图片url
    defaultImg() {
      // 这里需要假报错兼容
      // 数据没回来之前 this.skuImageList 是一个空数组
      // 取下标为0的是 undefined, und.xx  und点任何东西都报错
      return (this.skuImageList[this.index] || {}).imgUrl
    }
  },
  mounted() {
    this.$bus.$on('changeImg', this.changeImg)
  },
  methods: {
    changeImg(index) {
      this.index = index;
    },
    // 鼠标移动事件
    moveHandler(e) {
      // clientX & clientY
      // 拿的是鼠标相对视口的水平距离和垂直距离，相对的是视口的左上角（以视口左上角为原点）
      // pageX & pageY
      // 拿的是鼠标相对页面的水平距离和垂直距离，相对的是页面的左上角（以页面左上角为原点）
      // offsetX & offsetY
      // 拿的是鼠标相对自身元素的水平距离和垂直距离，相对的是自身元素左上角（以自身元素左上角为原点）

      // 获取鼠标实时位置
      let startX = e.offsetX;
      let startY = e.offsetY;


      // clientWidth
      // 拿的是盒子   内容 + padding的宽；
      // clientHeight
      // 拿的是盒子   内容 + padding的高；

      // offsetWidth
      // 拿的是盒子   内容 + padding + border的宽
      // offsetHeight
      // 拿的是盒子   内容 + padding + border的高
      // offsetLeft
      // 拿的是元素的偏移量：可以认为就是拿的绝对定位left值
      // offsetTop
      // 拿的是元素的偏移量：可以认为就是拿的绝对定位top值
      // 这两个值，相对的参照物和绝对定位完全一样；

      // scrollTop 可读可写
      // 拿的是盒子内容向上滚动的距离
      // scrollLeft 可读可写
      // 拿的是盒子内容向左滚动的距离


      // 计算出蒙层左上角的位置
      // 结束位置 = 起始位置 - 蒙层宽度/高度的一半
      let endX = startX - this.$refs.maskRef.clientWidth / 2;
      let endY = startY - this.$refs.maskRef.clientHeight / 2;

      // 边界判断
      if (endX < 0) {
        endX = 0;
      } else if (endX > this.$refs.eventRef.clientWidth - this.$refs.maskRef.clientWidth) {
        endX = this.$refs.eventRef.clientWidth - this.$refs.maskRef.clientWidth
      }

      if (endY < 0) {
        endY = 0
      } else if (endY > this.$refs.eventRef.clientHeight - this.$refs.maskRef.clientHeight) {
        endY = this.$refs.eventRef.clientHeight - this.$refs.maskRef.clientHeight
      }


      // 获取到蒙层,给蒙层设置位置
      this.$refs.maskRef.style.left = endX + 'px';
      this.$refs.maskRef.style.top = endY + 'px';


      // 分析得出 图片的位置 和 蒙层的位置是 -2 倍的关系
      // 给图片设置位置
      this.$refs.bigImgRef.style.left = endX * -2 + 'px';
      this.$refs.bigImgRef.style.top = endY * -2 + 'px';
    }
  }
}
</script>

<style lang="less">
  .spec-preview {
    position: relative;
    width: 400px;
    height: 400px;
    border: 1px solid #ccc;

    img {
      width: 100%;
      height: 100%;
    }

    .event {
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      z-index: 998;
    }

    .mask {
      width: 50%;
      height: 50%;
      background-color: rgba(0, 255, 0, 0.3);
      position: absolute;
      left: 0;
      top: 0;
      display: none;
    }

    .big {
      width: 100%;
      height: 100%;
      position: absolute;
      top: -1px;
      left: 100%;
      border: 1px solid #aaa;
      overflow: hidden;
      z-index: 998;
      display: none;
      background: white;

      img {
        width: 200%;
        max-width: 200%;
        height: 200%;
        position: absolute;
        left: 0;
        top: 0;
      }
    }

    .event:hover~.mask,
    .event:hover~.big {
      display: block;
    }
  }
</style>